package com.flute.icrawler.framework.processor.result;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.apache.log4j.Logger;

import com.flute.icrawler.framework.framework.BerkeleyCrawlUrlPool;
import com.flute.icrawler.framework.framework.CrawlUrl;
import com.flute.icrawler.framework.framework.ICrawlUrlPool;

/**
 * 对url处理的结果记录
 * 
 * @author Administrator
 * 
 */
public class CrawlUrlResult implements Serializable {

	private static Logger logger = Logger.getLogger(CrawlUrlResult.class);
	/**
	 * 
	 */
	private static final long serialVersionUID = 8079344401666846314L;

	/**
	 * 处理器的处理结果
	 */
	private List<IProcessResult> results;

	/**
	 * 排他性结果
	 */
	private IProcessResult uniqueResult;
	/**
	 * 是否能中断后续处理
	 */
	private volatile boolean canInterrupt;
	/**
	 * 处理过程中产生的中间结果参数
	 */
	private Hashtable<String, ResultParameter> resultParameters;

	public CrawlUrlResult() {
		this.results = new ArrayList<IProcessResult>();
		this.resultParameters = new Hashtable<String, ResultParameter>();
	}

	public void addProcessorResult(IProcessResult result) {
		if (result.isUnique()) {
			uniqueResult = result;
		} else {
			synchronized (results) {
				results.add(result);
			}
		}
		if (result.isNeedInterrupt()) {
			canInterrupt = true;
		}
	}

	/**
	 * 是否包含该结果
	 * 
	 * @param result
	 * @return
	 */
	public boolean contain(IProcessResult result) {
		for (int i = 0; i < results.size(); i++) {
			if (results.get(i).equals(result)) {
				return true;
			}
		}
		return false;
	}

	public List<IProcessResult> getResults() {
		return results;
	}

	public void addResultParameter(ResultParameter parameter) {
		this.resultParameters.put(parameter.getName(), parameter);
	}

	public ResultParameter getResultParameter(String name) {
		return resultParameters.get(name);
	}

	public void resetResultParameters() {
		resultParameters.clear();
	}

	public boolean isCanInterrupt() {
		return canInterrupt;
	}

	public void handle(CrawlUrl url, ICrawlUrlPool pool) {
		long time = System.currentTimeMillis();
		synchronized (results) {
			logger.info("results syn time:"
					+ (System.currentTimeMillis() - time) + "ms");
			if (0 == results.size()) {
				new FilterProcessorResult().handle(url, pool);
				return;
			}
			for (IProcessResult result : results) {
				long s = System.currentTimeMillis();
				result.handle(url, pool);
				logger.info(result + " handle time:"
						+ (System.currentTimeMillis() - s) + "ms");
			}
		}

		if (uniqueResult != null) {
			uniqueResult.handle(url, pool);
		} else {
			new SuccessProcessorResult().handle(url, pool);
		}
	}
}
